package uit.com.project.iCampus.map;

import java.util.ArrayList;
import java.util.List;

import uit.com.project.iCampus.activity.R;
import uit.com.project.iCampus.application.ICampusApp;
import uit.com.project.iCampus.model.BuildingInfo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class NearestBuildingCenterOverlay extends ItemizedOverlay<OverlayItem>{
	private Context context;
	private List<OverlayItem> items = new ArrayList<OverlayItem>();
	private BalloonOverlayView<OverlayItem> balloonView;
	private Drawable marker = null;
	//Balloon bottom padding
	private int viewOffset;
	private View clickRegion;
	private int currentFocussedIndex;
	private OverlayItem currentFocussedItem;
	private MapView mapView;
	
	public NearestBuildingCenterOverlay(Context context, MapView mapView, List<BuildingInfo> listBuildingInfo, Drawable marker) {
		super(marker);
		this.context = context;
		this.mapView = mapView;
		this.marker = marker;
		this.viewOffset = 10;
		
		GeoPoint geoPoint = null;
		BuildingInfo buildingInfo = null;
		for (int i = 0; i < listBuildingInfo.size(); i++) {
			buildingInfo = listBuildingInfo.get(i);
			geoPoint = new GeoPoint((int)(buildingInfo.getLatitude() * 1E6), (int)(buildingInfo.getLongitude() * 1E6));
			items.add(new OverlayItem(geoPoint, buildingInfo.getBuildingName(), "Address: " + buildingInfo.getDetail() ));
		}
		
		populate();
	}
	
	/**
	 * Set the horizontal distance between the marker and the bottom of the information
	 * balloon. The default is 0 which works well for center bounded markers. If your
	 * marker is center-bottom bounded, call this before adding overlay items to ensure
	 * the balloon hovers exactly above the marker. 
	 * 
	 * @param pixels - The padding between the center point and the bottom of the
	 * information balloon.
	 */
	public void setBalloonBottomOffset(int pixels) {
		viewOffset = pixels;
	}
	public int getBalloonBottomOffset() {
		return viewOffset;
	}
	
	/**
	 * Override this method to handle a "tap" on a balloon. By default, does nothing 
	 * and returns false.
	 * 
	 * @param index - The index of the item whose balloon is tapped.
	 * @param item - The item whose balloon is tapped.
	 * @return true if you handled the tap, otherwise false.
	 */
	protected boolean onBalloonTap(int index, OverlayItem item) {
		return false;
	}
	
	/**
	 * Creates the balloon view. Override to create a sub-classed view that
	 * can populate additional sub-views.
	 */
	protected BalloonOverlayView<OverlayItem> createBalloonOverlayView() {
		return new BalloonOverlayView<OverlayItem>(context, getBalloonBottomOffset());
	}

	@Override
	protected OverlayItem createItem(int i) {
		return items.get(i);
	}

	@Override
	public int size() {
		return items.size();
	}
	
	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);
		//Draw all item
		boundCenterBottom(marker);
	}
	
	public void drawMarker(MapView mapView, GeoPoint geoPoint, Canvas canvas, int imageId){
		// ---translate the GeoPoint to screen pixels---
		Point screenPts = new Point();
		mapView.getProjection().toPixels(geoPoint, screenPts);
		// ---add the marker---
		Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), imageId);
		canvas.drawBitmap(bmp, screenPts.x - (bmp.getWidth() / 2), screenPts.y - bmp.getHeight(), null);
	}
	
	@Override
	protected boolean onTap(int index) {
		ICampusApp.DESTINATION = items.get(index).getPoint();
		
		currentFocussedIndex = index;
		currentFocussedItem = createItem(index);

		boolean isRecycled;
		if (balloonView == null) {
			balloonView = createBalloonOverlayView();
			clickRegion = (View) balloonView.findViewById(R.id.balloon_inner_layout);
			clickRegion.setOnTouchListener(createBalloonTouchListener());
			isRecycled = false;
		} else {
			isRecycled = true;
		}

		balloonView.setVisibility(View.GONE);

		List<Overlay> mapOverlays = mapView.getOverlays();
		if (mapOverlays.size() > 1) {
			hideOtherBalloons(mapOverlays);
		}

		balloonView.setData(currentFocussedItem);

		GeoPoint point = currentFocussedItem.getPoint();
		MapView.LayoutParams params = new MapView.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
				MapView.LayoutParams.BOTTOM_CENTER);
		params.mode = MapView.LayoutParams.MODE_MAP;

		balloonView.setVisibility(View.VISIBLE);

		if (isRecycled) {
			balloonView.setLayoutParams(params);
		} else {
			mapView.addView(balloonView, params);
		}

		MapController mc = mapView.getController();
		mc.animateTo(point);

		return true;
	}
	
	/**
	 * Sets the visibility of this overlay's balloon view to GONE. 
	 */
	protected void hideBalloon() {
		if (balloonView != null) {
			balloonView.setVisibility(View.GONE);
		}
	}

	/**
	 * Hides the balloon view for any other BalloonItemizedOverlay instances
	 * that might be present on the MapView.
	 * 
	 * @param overlays - list of overlays (including this) on the MapView.
	 */
	private void hideOtherBalloons(List<Overlay> overlays) {
		for (Overlay overlay : overlays) {
			if (overlay instanceof NearestBuildingCenterOverlay && overlay != this) {
				((NearestBuildingCenterOverlay) overlay).hideBalloon();
			}
		}
	}

	/**
	 * Sets the onTouchListener for the balloon being displayed, calling the
	 * overridden {@link #onBalloonTap} method.
	 */
	private OnTouchListener createBalloonTouchListener() {
		return new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {

				View l =  ((View) v.getParent()).findViewById(R.id.balloon_main_layout);
				Drawable d = l.getBackground();

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					int[] states = {android.R.attr.state_pressed};
					if (d.setState(states)) {
						d.invalidateSelf();
					}
					return true;
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					int newStates[] = {};
					if (d.setState(newStates)) {
						d.invalidateSelf();
					}
					// call overridden method
					onBalloonTap(currentFocussedIndex, currentFocussedItem);
					return true;
				} else {
					return false;
				}

			}
		};
	}
	
}
